{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from cot import Collection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# collection = Collection.from_json(\"./thoughtsource_data/thoughtsource_1_empty.json\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loading worldtree...\n"
     ]
    }
   ],
   "source": [
    "collection = Collection([\"worldtree\"], verbose=False)\n",
    "collection = collection.select(number_samples=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "| Name      |   Train | Valid   | Test   |\n",
       "|-----------|---------|---------|--------|\n",
       "| worldtree |       1 | -       | -      |\n",
       "\n",
       "Not loaded: ['aqua', 'asdiv', 'commonsense_qa', 'entailment_bank', 'gsm8k', 'mawps', 'med_qa', 'medmc_qa', 'open_book_qa', 'pubmed_qa', 'qed', 'strategy_qa', 'svamp']"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "collection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "config={\n",
    "    \"cot_trigger_keys\": ['kojima-01'],\n",
    "    \"answer_extraction_keys\": ['kojima-A-D'], \n",
    "    \"author\" : \"konstantin\",\n",
    "    \"temperature\": 0,\n",
    "    \"max_tokens\": 512,\n",
    "    \"verbose\": False,\n",
    "    \"warn\": False,\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Generating worldtree...\n"
     ]
    }
   ],
   "source": [
    "collection.generate(config=config)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Evaluating worldtree...\n"
     ]
    }
   ],
   "source": [
    "collection.evaluate()\n",
    "collection.full_text_prompts()\n",
    "collection.dump(\"foo.json\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [],
   "source": [
    "api_model = [(\"openai\", \"text-davinci-003\"), (\"cohere\", \"command-xlarge-nightly\")]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Generating worldtree...\n",
      "Generating worldtree...\n"
     ]
    }
   ],
   "source": [
    "for api, model in api_model:\n",
    "    config[\"api_service\"] = api\n",
    "    config[\"engine\"] = model\n",
    "    collection.generate(config=config)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain import OpenAI, LLMChain, Prompt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "input = \"A parent and a child share several characteristics. Both individuals are tall, have curly hair, are good cooks, and have freckles. Which of these characteristics is a learned behavior?\\nA) being tall\\nB) having curly hair\\nC) being a good cook\\nD) having freckles\\n\\nAnswer: Let's think step by step.\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "template = \"{prompt}\"\n",
    "prompt = Prompt(template=template, input_variables=[\"prompt\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "engine = \"text-davinci-003\"\n",
    "max_tokens = 512\n",
    "temperature = 0.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "llm=OpenAI(\n",
    "    # parameter options: https://beta.openai.com/docs/api-reference/completions/create-completion\n",
    "    model_name=engine,\n",
    "    max_tokens=max_tokens,\n",
    "    temperature=temperature,\n",
    "    # type: ignore (suppress pylance error)\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "chain = LLMChain(\n",
    "    prompt=prompt,\n",
    "    llm=llm\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain import LLMCheckerChain"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "LLMCheckerChain"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 136,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "' Being tall and having curly hair are physical characteristics that are inherited, not learned. Having freckles is also a physical characteristic that is inherited. Therefore, the correct answer is C) being a good cook, which is a learned behavior.'"
      ]
     },
     "execution_count": 136,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "response = chain.predict(prompt=input, stop=None)\n",
    "response"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 137,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "OpenAI(cache=None, verbose=False, callback_manager=<langchain.callbacks.shared.SharedCallbackManager object at 0x7f93bbf55120>, client=<class 'openai.api_resources.completion.Completion'>, model_name='text-davinci-003', temperature=0.0, max_tokens=512, top_p=1, frequency_penalty=0, presence_penalty=0, n=1, best_of=1, model_kwargs={}, openai_api_key=None, batch_size=20, request_timeout=None, logit_bias={}, max_retries=6, streaming=False)"
      ]
     },
     "execution_count": 137,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "llm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 139,
   "metadata": {},
   "outputs": [
    {
     "ename": "ValidationError",
     "evalue": "2 validation errors for LLMChain\nprompt\n  Can't instantiate abstract class BasePromptTemplate with abstract methods _prompt_type, format (type=type_error)\nllm\n  Can't instantiate abstract class BaseLLM with abstract methods _agenerate, _generate, _llm_type (type=type_error)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mValidationError\u001b[0m                           Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[139], line 2\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39mlangchain\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39mchains\u001b[39;00m \u001b[39mimport\u001b[39;00m LLMChain\n\u001b[0;32m----> 2\u001b[0m chain \u001b[39m=\u001b[39m LLMChain(llm\u001b[39m=\u001b[39;49mllm, prompt\u001b[39m=\u001b[39;49mprompt)\n",
      "File \u001b[0;32m~/work/ThoughtSource/venv/lib/python3.10/site-packages/pydantic/main.py:342\u001b[0m, in \u001b[0;36mpydantic.main.BaseModel.__init__\u001b[0;34m()\u001b[0m\n",
      "\u001b[0;31mValidationError\u001b[0m: 2 validation errors for LLMChain\nprompt\n  Can't instantiate abstract class BasePromptTemplate with abstract methods _prompt_type, format (type=type_error)\nllm\n  Can't instantiate abstract class BaseLLM with abstract methods _agenerate, _generate, _llm_type (type=type_error)"
     ]
    }
   ],
   "source": [
    "from langchain.chains import LLMChain\n",
    "chain = LLMChain(llm=llm, prompt=prompt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.prompts import PromptTemplate\n",
    "from langchain.llms import OpenAI\n",
    "\n",
    "llm = OpenAI(temperature=0.9)\n",
    "prompt = PromptTemplate(\n",
    "    input_variables=[\"product\"],\n",
    "    template=\"What is a good name for a company that makes {product}?\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "Splashy Sox.\n"
     ]
    }
   ],
   "source": [
    "from langchain.chains import LLMChain\n",
    "chain = LLMChain(llm=llm, prompt=prompt)\n",
    "\n",
    "# Run the chain only specifying the input variable.\n",
    "print(chain.run(\"colorful socks\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "second_prompt = PromptTemplate(\n",
    "    input_variables=[\"company_name\"],\n",
    "    template=\"Write a catchphrase for the following company: {company_name}\",\n",
    ")\n",
    "chain_two = LLMChain(llm=llm, prompt=second_prompt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "ename": "ValidationError",
     "evalue": "1 validation error for SimpleSequentialChain\nreturn_all\n  extra fields not permitted (type=value_error.extra)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mValidationError\u001b[0m                           Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[18], line 2\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39mlangchain\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39mchains\u001b[39;00m \u001b[39mimport\u001b[39;00m SimpleSequentialChain\n\u001b[0;32m----> 2\u001b[0m overall_chain \u001b[39m=\u001b[39m SimpleSequentialChain(chains\u001b[39m=\u001b[39;49m[chain, chain_two], verbose\u001b[39m=\u001b[39;49m\u001b[39mTrue\u001b[39;49;00m, return_all\u001b[39m=\u001b[39;49m\u001b[39mTrue\u001b[39;49;00m)\n\u001b[1;32m      4\u001b[0m \u001b[39m# Run the chain specifying only the input variable for the first chain.\u001b[39;00m\n\u001b[1;32m      5\u001b[0m catchphrase \u001b[39m=\u001b[39m overall_chain\u001b[39m.\u001b[39mrun(\u001b[39m\"\u001b[39m\u001b[39mcolorful socks\u001b[39m\u001b[39m\"\u001b[39m)\n",
      "File \u001b[0;32m~/work/ThoughtSource/venv/lib/python3.10/site-packages/pydantic/main.py:342\u001b[0m, in \u001b[0;36mpydantic.main.BaseModel.__init__\u001b[0;34m()\u001b[0m\n",
      "\u001b[0;31mValidationError\u001b[0m: 1 validation error for SimpleSequentialChain\nreturn_all\n  extra fields not permitted (type=value_error.extra)"
     ]
    }
   ],
   "source": [
    "from langchain.chains import SimpleSequentialChain\n",
    "overall_chain = SimpleSequentialChain(chains=[chain, chain_two], verbose=True)\n",
    "\n",
    "# Run the chain specifying only the input variable for the first chain.\n",
    "catchphrase = overall_chain.run(\"colorful socks\")\n",
    "print(catchphrase)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "ename": "KeyError",
     "evalue": "'input_variables'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[19], line 2\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39mlangchain\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39mchains\u001b[39;00m \u001b[39mimport\u001b[39;00m SequentialChain\n\u001b[0;32m----> 2\u001b[0m overall_chain \u001b[39m=\u001b[39m SequentialChain(chains\u001b[39m=\u001b[39;49m[chain, chain_two], verbose\u001b[39m=\u001b[39;49m\u001b[39mTrue\u001b[39;49;00m, return_all\u001b[39m=\u001b[39;49m\u001b[39mTrue\u001b[39;49;00m)\n\u001b[1;32m      4\u001b[0m \u001b[39m# Run the chain specifying only the input variable for the first chain.\u001b[39;00m\n\u001b[1;32m      5\u001b[0m catchphrase \u001b[39m=\u001b[39m overall_chain\u001b[39m.\u001b[39mrun(\u001b[39m\"\u001b[39m\u001b[39mcolorful socks\u001b[39m\u001b[39m\"\u001b[39m)\n",
      "File \u001b[0;32m~/work/ThoughtSource/venv/lib/python3.10/site-packages/pydantic/main.py:340\u001b[0m, in \u001b[0;36mpydantic.main.BaseModel.__init__\u001b[0;34m()\u001b[0m\n",
      "File \u001b[0;32m~/work/ThoughtSource/venv/lib/python3.10/site-packages/pydantic/main.py:1051\u001b[0m, in \u001b[0;36mpydantic.main.validate_model\u001b[0;34m()\u001b[0m\n",
      "File \u001b[0;32m~/work/ThoughtSource/venv/lib/python3.10/site-packages/langchain/chains/sequential.py:45\u001b[0m, in \u001b[0;36mSequentialChain.validate_chains\u001b[0;34m(cls, values)\u001b[0m\n\u001b[1;32m     43\u001b[0m \u001b[39m\u001b[39m\u001b[39m\"\"\"Validate that the correct inputs exist for all chains.\"\"\"\u001b[39;00m\n\u001b[1;32m     44\u001b[0m chains \u001b[39m=\u001b[39m values[\u001b[39m\"\u001b[39m\u001b[39mchains\u001b[39m\u001b[39m\"\u001b[39m]\n\u001b[0;32m---> 45\u001b[0m input_variables \u001b[39m=\u001b[39m values[\u001b[39m\"\u001b[39;49m\u001b[39minput_variables\u001b[39;49m\u001b[39m\"\u001b[39;49m]\n\u001b[1;32m     46\u001b[0m known_variables \u001b[39m=\u001b[39m \u001b[39mset\u001b[39m(input_variables)\n\u001b[1;32m     47\u001b[0m \u001b[39mfor\u001b[39;00m chain \u001b[39min\u001b[39;00m chains:\n",
      "\u001b[0;31mKeyError\u001b[0m: 'input_variables'"
     ]
    }
   ],
   "source": [
    "from langchain.chains import SequentialChain\n",
    "overall_chain = SequentialChain(chains=[chain, chain_two], verbose=True, return_all=True)\n",
    "\n",
    "# Run the chain specifying only the input variable for the first chain.\n",
    "catchphrase = overall_chain.run(\"colorful socks\")\n",
    "print(catchphrase)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 130,
   "metadata": {},
   "outputs": [],
   "source": [
    "overall_chain.memory"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'\\n\\n\"Put a little color in your wardrobe - Get your colorful socks today!\"'"
      ]
     },
     "execution_count": 115,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "catchphrase"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new LLMCheckerChain chain...\u001b[0m\n",
      "\n",
      "\n",
      "\u001b[1m> Entering new SequentialChain chain...\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "from langchain.chains import LLMCheckerChain\n",
    "from langchain.llms import OpenAI\n",
    "\n",
    "llm = OpenAI(temperature=0)\n",
    "\n",
    "text = \"What type of mammal lays the biggest eggs?\"\n",
    "\n",
    "checker_chain = LLMCheckerChain(llm=llm, verbose=True)\n",
    "\n",
    "result = checker_chain.run(text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'question': 'What type of mammal lays the biggest eggs?',\n",
       " 'statement': '\\nThe largest mammal that lays eggs is the platypus.',\n",
       " 'assertions': '\\n• Platypus is a mammal \\n• Mammals can lay eggs \\n• Platypus is the largest mammal that lays eggs',\n",
       " 'checked_assertions': '\\n• Platypus is a mammal: True\\n• Mammals can lay eggs: False - Mammals are viviparous, meaning they give birth to live young.\\n• Platypus is the largest mammal that lays eggs: False - The largest mammal that lays eggs is the echidna, which is a monotreme like the platypus.',\n",
       " 'revised_statement': ' The echidna is the largest mammal that lays eggs.'}"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "' The platypus is the largest mammal that lays eggs.'"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "# This is an LLMChain to write a synopsis given a title of a play and the era it is set in.\n",
    "llm = OpenAI(temperature=.7)\n",
    "template = \"\"\"You are a playwright. Given the title of play and the era it is set in, it is your job to write a synopsis for that title.\n",
    "\n",
    "Title: {title}\n",
    "Era: {era}\n",
    "Playwright: This is a synopsis for the above play:\"\"\"\n",
    "prompt_template = PromptTemplate(input_variables=[\"title\", 'era'], template=template)\n",
    "synopsis_chain = LLMChain(llm=llm, prompt=prompt_template, output_key=\"synopsis\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "# This is an LLMChain to write a review of a play given a synopsis.\n",
    "llm = OpenAI(temperature=.7)\n",
    "template = \"\"\"You are a play critic from the New York Times. Given the synopsis of play, it is your job to write a review for that play.\n",
    "\n",
    "Play Synopsis:\n",
    "{synopsis}\n",
    "Review from a New York Times play critic of the above play:\"\"\"\n",
    "prompt_template = PromptTemplate(input_variables=[\"synopsis\"], template=template)\n",
    "review_chain = LLMChain(llm=llm, prompt=prompt_template, output_key=\"review\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "# This is the overall chain where we run these two chains in sequence.\n",
    "from langchain.chains import SequentialChain\n",
    "overall_chain = SequentialChain(\n",
    "    chains=[synopsis_chain, review_chain],\n",
    "    input_variables=[\"era\", \"title\"],\n",
    "    # Here we return multiple variables\n",
    "    output_variables=[\"synopsis\", \"review\"],\n",
    "    verbose=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new SequentialChain chain...\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "review = overall_chain({\"title\":\"Tragedy at sunset on the beach\", \"era\": \"Victorian England\"})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'title': 'Tragedy at sunset on the beach',\n",
       " 'era': 'Victorian England',\n",
       " 'synopsis': \"\\n\\nTragedy at sunset on the beach is a tale of love, loss, and sorrow set in Victorian England. It follows the story of a young couple, John and Mary, who have been deeply in love since they first met. Despite their growing love, their families are from opposite sides of the social divide and forbid the two to be together. In a last-ditch effort to be together, John and Mary decide to elope and escape to the beach, where they plan to get married. \\n\\nOn their way to the beach, they are stopped by John's father, who has followed them in a desperate attempt to keep them apart. In a desperate moment, John's father shoots Mary, killing her instantly. John is left heartbroken and alone on the beach, surrounded by the setting sun. \\n\\nThis tragedy serves as a reminder of the power of social divide and the strength of true love. In the end, John is left to mourn his lost love while the audience is left to ponder the fragility of life.\",\n",
       " 'review': '\\n\\nTragedy at Sunset on the Beach is a powerfully evocative and passionate exploration of love, loss, and grief. It is a timeless tale of forbidden love, set in Victorian England, that still resonates with audiences today. \\n\\nThe play expertly crafts a story of two star-crossed lovers, John and Mary, who are torn apart by the social divide of their families. The audience is brought along on an emotional journey as they attempt to elope and be together, only to have their dreams shattered by a desperate and ultimately tragic act. \\n\\nThe writing is beautiful, the acting is superb, and the production is stunning. The setting of the beach at sunset is the perfect backdrop for this tragedy, and the audience is left to ponder the fragility of life and the strength of true love. \\n\\nTragedy at Sunset on the Beach is a must-see play that will leave you questioning the power of social divides and the strength of love. It is a thoughtful and moving performance that will stay with you long after the curtain falls.'}"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "review"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.6"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "ccbfa654f25866afe66a1c016d0b518a994fbe20a93c2d8b432dbe114020e2d2"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
